﻿#pragma once
#include "MathDefine.hpp"
#include <string>

_NNU_DGGS_BEGIN
using namespace Base;
namespace Base
{
    // 基菱形参数
    const int baseDiamondCount = 10;
    const long double baseDiamondLat = 26.565051177L;
    const long double baseDiamondWidth = 72.0L;
    const long double baseDiamondHeight = 90.0L + baseDiamondLat;

    // 当前支持最大层级
    //static const unsigned int maxLevel = 30;
    static const unsigned int MaxLevel = 30;


    /// <summary>
    /// 格网单元类型
    /// </summary>
    enum class DGGSGridType
    {
        DGGS_ISEA4H, // 施耐德等积投影四孔六边形网格
        DGGS_ISEA3H, // 施耐德等积投影三孔六边形网格
        DGGS_ISEA4T, // 施耐德等积投影四孔三角形网格
        DGGS_ISEA4D, // 施耐德等积投影四孔菱形网格
        Unknown
    };

    /// <summary>
    /// 格网要素类型
    /// </summary>
    enum class DGGSElementType
    {
        Vertex,     // 格点
        Edge,       // 格边
        Cell,       // 格元
        SideEdge,   // 棱边
        SideFace,   // 侧面
        Voxel,      // 体
        Unknown
    };

    /// <summary>
    /// 拓扑查询类型
    /// </summary>
    /**
     * ———————————————————————————————————————————————————————————————————————————————————————————————————————
     *               |  RelativeVertexes  |          RelativeEdges       |    RelativeCells    |      RelativeVoxels    (topoType)
     *   (startcode)————————————————————————————————————————————————————————————————————————————————————————————————
     *   vertex      |     格点相邻点       |      从vertex引出、进入的格边   |   参与组成的所有格元    |     参与组成的所有体元
     *
     *   edge        |     格边的端点       |      有一个共同端点的其他格边    |   格边两侧/四侧的格元   |    以edge为一边的所有体元
     *
     *   cell        |     格元的顶点       |            格元边界           |       相邻格元        |       格元的两侧体元
     *
     *   voxel       |     体元的顶点       |           体元所有棱边         |      体元所有面       |       相邻的所有体元
     *   ———————————————————————————————————————————————————————————————————————————————————————————————————————————
    **/
    enum class DGGSTopoType
    {
        UnKnown,            //默认未知
        RelativeVertexes,   //查询相邻格点
        RelativeEdges,      //查询相邻格边
        RelativeCells,      //查询相邻格元
        RelativeVoxels,     //查询相邻格体
        Parent,             //查询父格元
        Children,           //查询子格元
        Siblings            //查询兄弟格元
    };

    /// </summary>
    ///格网数据类型
    /// </summary>
    typedef enum {
        /*! Unknown or unspecified type */          DGGS_Unknown = 0,
        /*! Eight bit unsigned integer */           DGGS_Byte = 1,
        /*! Sixteen bit unsigned integer */         DGGS_UInt16 = 2,
        /*! Sixteen bit signed integer */           DGGS_Int16 = 3,
        /*! Thirty two bit unsigned integer */      DGGS_UInt32 = 4,
        /*! Thirty two bit signed integer */        DGGS_Int32 = 5,
        /* TODO?(#6879): GDT_UInt64 */
        /* TODO?(#6879): GDT_Int64 */
        /*! Thirty two bit floating point */        DGGS_Float32 = 6,
        /*! Sixty four bit floating point */        DGGS_Float64 = 7,
        /*! Complex Int16 */                        DGGS_CInt16 = 8,
        /*! Complex Int32 */                        DGGS_CInt32 = 9,
        /* TODO?(#6879): GDT_CInt64 */
        /*! Complex Float32 */                      DGGS_CFloat32 = 10,
        /*! Complex Float64 */                      DGGS_CFloat64 = 11,
        DGGS_TypeCount = 12          /* maximum type # + 1 */
    } DGGSDataType;


    /// <summary>
    /// 格网要素编码定义
    /// </summary>
    struct DGGSElementCode
    {
        DGGSElementType elementType=DGGSElementType::Unknown;       // 要素类型
        int levelZ=-1;                                              // 纵向层级
        float height=-10;                                           // 纵向高度
        int level=-1;                                               // 横向层级
        int basePartition=-1;                                       // 基菱形号
        long long int row=-1;                                       // 行号
        long long int col=-1;                                       // 列号

         bool operator==(const DGGSElementCode &other) const
        {
            if(this->elementType==other.elementType&&this->level==other.level&&this->levelZ==other.levelZ&&
               this->basePartition==other.basePartition&&this->row==other.row&&this->col==other.col)
                return true;
            else
                return false;
        }

         bool operator>(const DGGSElementCode &other) const
        {
            if(this->elementType==other.elementType&&this->level==other.level)
            {
                return this->basePartition>other.basePartition||(this->basePartition==other.basePartition &&this->row > other.row) || (this->basePartition==other.basePartition && this->row == other.row && this->col > other.col);
            }
            else
                return false;
        }

         bool operator<(const DGGSElementCode &other) const
        {
            if(this->elementType==other.elementType&&this->level==other.level)
            {
                return this->basePartition<other.basePartition||(this->basePartition==other.basePartition &&this->row < other.row) || (this->basePartition==other.basePartition && this->row == other.row && this->col < other.col);
            }
            else
                return false;
        }

         bool operator!=(const DGGSElementCode &other) const
        {
            if(this->elementType==other.elementType&&this->level==other.level&&this->levelZ==other.levelZ&&
               this->basePartition==other.basePartition&&this->row==other.row&&this->col==other.col)
                return false;
            else
                return true;
        }

    };


    /// <summary>
    /// 格网要素编码迭代器
    /// </summary>
    struct DGGSElementCodeIter
    {
        DGGSElementCode code;
        DGGSElementCodeIter* next = nullptr;
    };

}
/// </summary>
///正二十面体大菱形面结构
/// </summary>
struct DGGridDiamond
{
    DGGridDiamond(int a, double b, double c, double d, double e)
    {
        basePartition = a;
        lonMin = b;
        lonMax = c;
        latMin = d;
        latMax = e;
    }
    DGGridDiamond() {
        basePartition=-1;
        lonMax=0;
        lonMin=0;
        latMax=0;
        latMin=0;
    }
    int basePartition=-1;
    double lonMax=0;
    double lonMin=0;
    double latMax=0;
    double latMin=0;
};


/// </summary>
/// 格网系统下的AABB包围盒
/// </summary>
struct DGGridBBox
{
    int basePartition=-1;
    long long int rowMin =-1;
    long long int rowSize=-1;
    long long int colSize=-1;
    long long int colMax =-1;

    DGGridBBox& operator=(const DGGridBBox &other)
    {
        this->basePartition=other.basePartition;
        this->colMax=other.colMax;
        this->rowMin=other.rowMin;
        this->colSize=other.colSize;
        this->rowSize=other.rowSize;
        return *this;
    }
};




/// </summary>
///格网单元类型enum转为std::string
/// </summary>
inline std::string enum2String(Base::DGGSElementType elementType)
{
    switch (elementType)
    {
        case Base::DGGSElementType::Vertex:
            return "Vertex";
        case Base::DGGSElementType::Edge:
            return "Edge";
        case Base::DGGSElementType::Cell:
            return "Cell";
        case Base::DGGSElementType::Voxel:
            return"Voxel";
        default:
            return nullptr;
    }
}

/// </summary>
///格网类型enum转为std::string
/// </summary>
inline std::string enum2String(Base::DGGSGridType gridType)
{
    switch (gridType)
    {
        case Base::DGGSGridType::DGGS_ISEA4T:
            return "DGGS_ISEA4T";
        case Base::DGGSGridType::DGGS_ISEA4D:
            return "DGGS_ISEA4D";
        case Base::DGGSGridType::DGGS_ISEA4H:
            return "DGGS_ISEA4H";
        case Base::DGGSGridType::DGGS_ISEA3H:
            return"DGGS_ISEA3H";
        default:
            return nullptr;
    }
}

/// </summary>
///拓扑类型由enum转为std::string
/// </summary>
inline std::string enum2String(Base::DGGSTopoType topoType)
{
    switch (topoType)
    {
        case Base::DGGSTopoType::RelativeVertexes:
            return "RelativeVertexes";
        case Base::DGGSTopoType::RelativeEdges:
            return "RelativeEdges";
        case Base::DGGSTopoType::RelativeCells:
            return "RelativeCells";
        case Base::DGGSTopoType::RelativeVoxels:
            return "RelativeVoxels";
        case Base::DGGSTopoType::Parent:
            return "Parent";
        case Base::DGGSTopoType::Children:
            return "Children";
        case Base::DGGSTopoType::Siblings:
            return "Siblings";
        default:
            return nullptr;
    }
}

/// </summary>
///数据类型由enum转为std::string
/// </summary>
inline std::string enum2String(DGGSDataType dataType)
    {
        switch (dataType)
        {
            case DGGS_Byte:
                return "DGGS_Byte";
            case DGGS_UInt16:
                return "DGGS_UInt16";
            case DGGS_Int16:
                return "DGGS_Int16";
            case DGGS_UInt32:
                return "DGGS_UInt32";
            case DGGS_Int32:
                return "DGGS_Int32";
            case DGGS_Float32:
                return "DGGS_Float32";
            case DGGS_Float64:
                return "DGGS_Float64";
            default:
                return "";
        }
    }

/// </summary>
///格网类型std::string转为enum
/// </summary>
inline Base::DGGSGridType getGridTypeFromStr(const std::string& str)
{
    if (str=="DGGS_ISEA4T")
        return Base::DGGSGridType::DGGS_ISEA4T;
    if (str=="DGGS_ISEA4D")
        return Base::DGGSGridType::DGGS_ISEA4D;
    if (str=="DGGS_ISEA4H")
        return Base::DGGSGridType::DGGS_ISEA4H;
    if (str=="DGGS_ISEA3H")
        return Base::DGGSGridType::DGGS_ISEA3H;
    else
        return Base::DGGSGridType::Unknown;
}

/// </summary>
///拓扑类型string转为enum
/// </summary>
inline Base::DGGSTopoType getTopoTypeFromStr(const std::string& str) {
    if (str == "RelativeVertexes")
        return Base::DGGSTopoType::RelativeVertexes;
    if (str == "RelativeEdges")
        return Base::DGGSTopoType::RelativeEdges;
    if (str == "RelativeCells")
        return Base::DGGSTopoType::RelativeCells;
    if (str == "RelativeVoxels")
        return Base::DGGSTopoType::RelativeVoxels;
    if (str == "Parent")
        return Base::DGGSTopoType::Parent;
    if (str == "Children")
        return Base::DGGSTopoType::Children;
    if (str == "Siblings")
        return Base::DGGSTopoType::Siblings;
    else
        return Base::DGGSTopoType::UnKnown;
}

/// </summary>
///格网要素类型string转为enum
/// </summary>
inline Base::DGGSElementType getElementTypeFromStr(const std::string& str) {
    if (str == "Vertex")
        return Base::DGGSElementType::Vertex;
    if (str == "Edge")
        return Base::DGGSElementType::Edge;
    if (str == "Cell")
        return Base::DGGSElementType::Cell;
    if (str == "Voxel")
        return Base::DGGSElementType::Voxel;
    else
        return Base::DGGSElementType::Unknown;
}

/// </summary>
///格网要素类型string转为enum
/// </summary>
inline DGGSDataType getDataTypeFromStr(const std::string& str) {
    if (str == "DGGS_Byte")
        return DGGSDataType::DGGS_Byte;
    if (str == "DGGS_UInt16")
        return DGGSDataType::DGGS_UInt16;
    if (str == "DGGS_Int16")
        return DGGSDataType::DGGS_Int16;
    if (str == "DGGS_UInt32")
        return DGGSDataType::DGGS_UInt32;
    if (str == "DGGS_Int32")
        return DGGSDataType::DGGS_Int32;
    if (str == "DGGS_Float32")
        return DGGSDataType::DGGS_Float32;
    if (str == "DGGS_Float64")
        return DGGSDataType::DGGS_Float64;
    else
        return DGGSDataType::DGGS_Unknown; // 假设你有一个Unknown枚举值
}


/// <summary>
/// 获取格网的行数
/// </summary>
inline long long int rowMaxSize(int level)
{
    return (long long int) pow(2, level);
}

/// <summary>
/// 获取格网的面列数
/// </summary>
inline long long int fColMaxSize(int level, DGGSGridType gridType)
{
    switch (gridType) {
        case DGGSGridType::DGGS_ISEA4H:
            return (long long int)pow(2, level);
        case DGGSGridType::DGGS_ISEA4D:
            return (long long int)pow(2, level);
        case DGGSGridType::DGGS_ISEA4T:
            return (long long int)pow(2, level + 1);
        default:
            return -1;
    }
}

/// <summary>
/// 获取格网的点列数
/// </summary>
inline long long int vColMaxSize(int level, DGGSGridType gridType) {
    switch (gridType) {
        case DGGSGridType::DGGS_ISEA4H:
            return (long long int) pow(2, level) * 2;
        case DGGSGridType::DGGS_ISEA4D:
            return (long long int) pow(2, level);
        case DGGSGridType::DGGS_ISEA4T:
            return (long long int) pow(2, level);
        default:
            return -1;
    }
}

/// <summary>
/// 获取格网的边列数
/// </summary>
inline long long int eColMaxSize(int level, DGGSGridType gridType) {
    switch (gridType)
    {
        case DGGSGridType::DGGS_ISEA4H:
            return (long long int) pow(2, level) * 3;
        case DGGSGridType::DGGS_ISEA4D:
            return (long long int) pow(2, level) * 2;
        case DGGSGridType::DGGS_ISEA4T:
            return (long long int) pow(2, level) * 3;
        default:
            return -1;
    }
}

/// <summary>
/// 获取最大列数
/// </summary>
inline long long int colMaxSize(DGGSElementCode code, DGGSGridType gridType) {
    auto maxCol = (long long int) pow(2, code.level);
    switch (code.elementType) {
        case DGGSElementType::Vertex:
        case DGGSElementType::SideEdge:
            maxCol = vColMaxSize(code.level, gridType);
            break;
        case DGGSElementType::Edge:
        case DGGSElementType::SideFace:
            maxCol = eColMaxSize(code.level, gridType);
            break;
        case DGGSElementType::Cell:
        case DGGSElementType::Voxel:
            maxCol = fColMaxSize(code.level, gridType);
            break;
        default:
            break;
    }
    return maxCol;
}

/// <summary>
/// 获取菱形code对应的格网id
/// </summary>
inline long long int diaCode2Id(DGGSElementCode code) {
    auto maxCol = colMaxSize(code, DGGSGridType::DGGS_ISEA4D);
    auto maxRow = (long long int) pow(2, code.level);
    long long int maxFace = maxCol * maxRow;

    int originStep = 0;
    switch (code.elementType) {
        case DGGSElementType::Vertex:
        case DGGSElementType::SideEdge:
            originStep = 1;
            break;
        case DGGSElementType::Edge:
        case DGGSElementType::SideFace:
            originStep = 0;
            break;
        case DGGSElementType::Cell:
        case DGGSElementType::Voxel:
            originStep = 0;
            break;
        case DGGSElementType::Unknown:
            break;
    }

    if (code.basePartition == 0)
        return code.row * maxCol + code.col;
    else
        return (code.basePartition - 1) * maxFace + code.row * maxCol + code.col + originStep;

}

/// <summary>
/// 获取三角形code对应的格网id
/// </summary>
inline long long int traCode2Id(DGGSElementCode code) {
    auto maxCol = colMaxSize(code, DGGSGridType::DGGS_ISEA4T);
    auto maxRow = (long long int) pow(2, code.level);
    long long int maxFace = maxCol * maxRow;

    int originStep = 0;
    switch (code.elementType) {
        case DGGSElementType::Vertex:
        case DGGSElementType::SideEdge:
            originStep = 1;
            break;
        case DGGSElementType::Edge:
        case DGGSElementType::SideFace:
            originStep = 0;
            break;
        case DGGSElementType::Cell:
        case DGGSElementType::Voxel:
            originStep = 0;
            break;
        case DGGSElementType::Unknown:
            break;
    }

    if (code.basePartition == 0)
        return code.row * maxCol + code.col;
    else
        return (code.basePartition - 1) * maxFace + code.row * maxCol + code.col + originStep;

}

/// <summary>
/// 获取六边形code对应的格网id
/// </summary>
inline long long int hexCode2Id(DGGSElementCode code) {
    auto maxCol = colMaxSize(code, DGGSGridType::DGGS_ISEA4H);
    auto maxRow = (long long int) pow(2, code.level);
    long long int maxFace = maxCol * maxRow;

    int originStep = 0;
    switch (code.elementType) {
        case DGGSElementType::Vertex:
        case DGGSElementType::SideEdge: {
            originStep = 5;
            maxFace = maxCol * maxRow - 1;
            break;
        }
        case DGGSElementType::Edge:
        case DGGSElementType::SideFace: {
            originStep = 5;
            maxFace = maxCol * maxRow - 1;
            break;
        }
        case DGGSElementType::Cell:
        case DGGSElementType::Voxel:
            originStep = 1;
            break;
        case DGGSElementType::Unknown:
            break;
    }

    if (code.basePartition == 0)
        return code.row * maxCol + code.col;
    else {
        if (code.row == 0)
            return (code.basePartition - 1) * maxFace + code.col + originStep;
        else {
            if (code.elementType == DGGSElementType::Cell || code.elementType == DGGSElementType::Voxel)
                return (code.basePartition - 1) * maxFace + code.row * maxCol + code.col + originStep;
            else
                return (code.basePartition - 1) * maxFace + code.row * maxCol - 1 + code.col + originStep;
        }
    }

}

/// <summary>
/// 获取code的id
/// </summary>
/// <param name="code">格网编码</param>
/// <param name="gridType">格网类型</param>
/// <returns>Id</returns>
inline long long int code2Id(DGGSElementCode code, DGGSGridType gridType) {
    switch (gridType) {
        case DGGSGridType::DGGS_ISEA4H:
            return hexCode2Id(code);
        case DGGSGridType::DGGS_ISEA4T:
            return traCode2Id(code);
        case DGGSGridType::DGGS_ISEA4D:
            return diaCode2Id(code);
        default:
            break;
    }
    return 0;
}

/// <summary>
/// 获取菱形codeId对应的格网编码
/// </summary>
inline void diaId2Code(long long int codeId, DGGSElementCode &code) {
    auto maxCol = colMaxSize(code, DGGSGridType::DGGS_ISEA4D);
    auto maxRow = (long long int) pow(2, code.level);
    auto maxFace = maxCol * maxRow;

    int originStep = 0;
    switch (code.elementType) {
        case DGGSElementType::Vertex:
        case DGGSElementType::SideEdge:
            originStep = 1;
            if (originStep > codeId) {
                code.basePartition = 0;
                code.row = 0;
                code.col = 0;
            } else {
                codeId -= originStep;
                code.col = codeId % maxCol;
                code.row = int(codeId % maxFace / maxCol);
                code.basePartition = int(codeId / maxFace) + 1;

            }
            return;
        case DGGSElementType::Edge:
        case DGGSElementType::SideFace:
            originStep = 0;
            codeId -= originStep;
            code.col = codeId % maxCol;
            code.row = int(codeId % maxFace / maxCol);
            code.basePartition = int(codeId / maxFace) + 1;
            return;
        case DGGSElementType::Cell:
        case DGGSElementType::Voxel:
            originStep = 0;
            codeId -= originStep;
            code.col = codeId % maxCol;
            code.row = int(codeId % maxFace / maxCol);
            code.basePartition = int(codeId / maxFace) + 1;
            return;
        default:
            return;
    }
}

/// <summary>
/// 获取三角形codeId对应的格网编码
/// </summary>
inline void traId2Code(long long int codeId, DGGSElementCode &code) {
    auto maxCol = colMaxSize(code, DGGSGridType::DGGS_ISEA4T);
    auto maxRow = (long long int) pow(2, code.level);
    auto maxFace = maxCol * maxRow;

    int originStep = 0;
    switch (code.elementType) {
        case DGGSElementType::Vertex:
        case DGGSElementType::SideEdge:
            originStep = 1;
            if (originStep > codeId) {
                code.basePartition = 0;
                code.row = 0;
                code.col = 0;
            } else {
                codeId -= originStep;
                code.col = codeId % maxCol;
                code.row = int(codeId % maxFace / maxCol);
                code.basePartition = int(codeId / maxFace) + 1;
            }
            return;
        case DGGSElementType::Edge:
        case DGGSElementType::SideFace:
            originStep = 0;
            codeId -= originStep;
            code.col = codeId % maxCol;
            code.row = int(codeId % maxFace / maxCol);
            code.basePartition = int(codeId / maxFace) + 1;
            return;
        case DGGSElementType::Cell:
        case DGGSElementType::Voxel:
            originStep = 0;
            codeId -= originStep;
            code.col = codeId % maxCol;
            code.row = int(codeId % maxFace / maxCol);
            code.basePartition = int(codeId / maxFace) + 1;
            return;
        default:
            return;
    }
}

/// <summary>
/// 获取六边形codeId对应的格网编码
/// </summary>
inline void hexId2Code(long long int codeId, DGGSElementCode &code) {
    auto maxCol = colMaxSize(code, DGGSGridType::DGGS_ISEA4H);
    auto maxRow = (long long int) pow(2, code.level);
    auto maxFace = maxCol * maxRow;

    int originStep = 0;
    switch (code.elementType) {
        case DGGSElementType::Vertex:
        case DGGSElementType::SideEdge:
            originStep = 5;
            maxFace -= 1;
            if (originStep > codeId) {
                code.basePartition = 0;
                code.row = 0;
                code.col = originStep;
            } else {
                codeId -= originStep;
                code.basePartition = int(codeId / maxFace) + 1;
                codeId -= (code.basePartition - 1) * maxFace;
                code.row = int(codeId / maxCol);
                codeId -= code.row * maxCol;
                if (code.row == 0)
                    code.col = codeId;
                else
                    code.col = codeId + 1;
                if (code.col == maxCol) {
                    code.col = 0;
                    code.row++;
                }
                if (code.row == maxRow) {
                    code.row = 0;
                    code.basePartition++;
                }
            }
            return;
        case DGGSElementType::Edge:
        case DGGSElementType::SideFace:
            originStep = 5;
            maxFace -= 1;
            if (originStep > codeId) {
                code.basePartition = 0;
                code.row = 0;
                code.col = originStep;
            } else {
                codeId -= originStep;
                code.basePartition = int(codeId / maxFace) + 1;
                codeId -= (code.basePartition - 1) * maxFace;
                code.row = int(codeId / maxCol);
                codeId -= code.row * maxCol;
                if (code.row == 0)
                    code.col = codeId;
                else
                    code.col = codeId + 1;
                if (code.col == maxCol) {
                    code.col = 0;
                    code.row++;
                }
                if (code.row == maxRow) {
                    code.row = 0;
                    code.basePartition++;
                }
            }
            return;
        case DGGSElementType::Cell:
        case DGGSElementType::Voxel:
            originStep = 1;
            if (originStep > codeId) {
                code.basePartition = 0;
                code.row = 0;
                code.col = originStep;
            } else {
                codeId -= originStep;
                code.col = codeId % maxCol;
                code.row = int(codeId % maxFace / maxCol);
                code.basePartition = int(codeId / maxFace) + 1;

            }
            return;
        default:
            return;
    }
}

/// <summary>
/// 获取codeId对应的格网编码
/// </summary>
/// <param name="codeId">格网Id</param>
/// <param name="code">格网编码</param>
/// <param name="gridType">格网类型</param>
inline void id2Code(long long int codeId, DGGSElementCode &code, DGGSGridType gridType) {
    switch (gridType) {
        case DGGSGridType::DGGS_ISEA4H:
            hexId2Code(codeId, code);
            break;
        case DGGSGridType::DGGS_ISEA4T:
            traId2Code(codeId, code);
            break;
        case DGGSGridType::DGGS_ISEA4D:
            diaId2Code(codeId, code);
            break;
        default:
            break;
    }
}


/// <summary>
/// 获取范围内基菱形
/// </summary>
/// <param name="boundBox">经纬度范围</param>
/// <param name="result">该范围内的菱形号</param>
/// <param name="partCount">该范围内的基菱数</param>
inline void getBasePartitions(const double *boundBox, int *&result, int &partCount)
{
    partCount=0;
    int pBasePartitions[11] = {};
    //获取范围多边形
    GeoCoord leftUpCoord = {boundBox[2], boundBox[0]};
    GeoCoord leftDownCoord = {boundBox[2], boundBox[1]};
    GeoCoord rightUpCoord = {boundBox[3], boundBox[0]};
    GeoCoord rightDownCoord = {boundBox[3], boundBox[1]};
    auto rangePolygon = new GeoCoord[5];
    rangePolygon[0] = leftUpCoord;
    rangePolygon[1] = rightUpCoord;
    rangePolygon[2] = rightDownCoord;
    rangePolygon[3] = leftDownCoord;
    rangePolygon[4] = leftUpCoord;


    GeoCoord *tagPolygon = nullptr;
    tagPolygon = new GeoCoord[6];
    //判断是否与0-5号菱形相交
    for (int i = 0; i < 5; i++) {
        tagPolygon[0] = {-180.0 + 0 + 72.0 * i, 26.56505};
        tagPolygon[1] = {-180 + 0 + 72.0 * i, 90};
        tagPolygon[2] = {-180 + 72 + 72.0 * i, 90};
        tagPolygon[3] = {-180 + 72 + 72.0 * i, 26.56505};
        tagPolygon[4] = {-180 + 36 + 72.0 * i, -26.56505};
        tagPolygon[5] = {-180 + 0 + 72.0 * i, 26.56505};
        if (Intersect(rangePolygon, 5, tagPolygon, 6) || isPointInPolygon(tagPolygon, 6, leftUpCoord))
            pBasePartitions[partCount++] = i + 1;
    }

    //判断是否与6-9号菱形相交
    for (int i = 6; i < 10; i++) {
        tagPolygon[0] = {-180 + 36 + 72.0 * (i - 6), -26.56505};
        tagPolygon[1] = {-180 + 36 + 72.0 * (i - 6), -90};
        tagPolygon[2] = {-180 + 36 + 72 + 72.0 * (i - 6), -90};
        tagPolygon[3] = {-180 + 36 + 72 + 72.0 * (i - 6), -26.56505};
        tagPolygon[4] = {-180 + 72 + 72.0 * (i - 6), 26.56505};
        tagPolygon[5] = {-180 + 36 + 72.0 * (i - 6), -26.56505};
        if (Intersect(rangePolygon, 5, tagPolygon, 6) || isPointInPolygon(tagPolygon, 6, leftUpCoord))
            pBasePartitions[partCount++] = i;
    }

    //判断是否与10号菱形相交
    auto tenthPartLeft = new GeoCoord[5];
    tenthPartLeft[0] = {-180 + 0, -90};
    tenthPartLeft[1] = {-180 + 0, 26.56505};
    tenthPartLeft[2] = {-180 + 36, -26.56505};
    tenthPartLeft[3] = {-180 + 36, -90};
    tenthPartLeft[4] = {-180 + 0, -90};

    auto tenthPartRight = new GeoCoord[5];
    tenthPartRight[0] = {180 - 32, -90};
    tenthPartRight[1] = {180 - 32, -26.56505};
    tenthPartRight[2] = {180 - 0, 26.56505};
    tenthPartRight[3] = {180 - 0, -90};
    tenthPartRight[4] = {180 - 32, -90};

    if (Intersect(rangePolygon, 5, tenthPartLeft, 5) || Intersect(rangePolygon, 5, tenthPartRight, 5) ||
        isPointInPolygon(tenthPartLeft, 5, leftUpCoord) || isPointInPolygon(tenthPartRight, 5, leftUpCoord))
        pBasePartitions[partCount++] = 10;

    //保存结果
    result = new int[partCount];
    for (int i = 0; i < partCount; i++)
        result[i] = pBasePartitions[i];

    //释放内存
    delete[]tagPolygon;
    tagPolygon = nullptr;
    delete[]tenthPartLeft;
    tenthPartLeft = nullptr;
    delete[]tenthPartRight;
    tenthPartRight = nullptr;
}


/// <summary>
/// 获取基菱形的经纬度包围盒
/// </summary>
inline DGGridDiamond getDiamond(int pBasePartition) {
    if (pBasePartition < 6 && pBasePartition > 0) {
        DGGridDiamond diamond = {
                pBasePartition,
                -180.0 + (pBasePartition - 1) * 72.0,
                -180.0 + pBasePartition * 72.0,
                -26.56505,
                90
        };
        return diamond;
    } else if (pBasePartition < 10) {
        DGGridDiamond diamond = {
                pBasePartition,
                -180.0 + (pBasePartition - 6) * 72.0 + 36.0,
                -180.0 + (pBasePartition - 5) * 72.0 + 36.0,
                -90,
                26.56505

        };
        return diamond;
    } else if (pBasePartition == 10) {
        DGGridDiamond diamond = {
                10,
                144.0,
                -144.0,
                -90,
                26.56505
        };
        return diamond;
    } else {
        DGGridDiamond diamond = {
                -1,
                180.0,
                -180.0,
                -90,
                90
        };
        return diamond;
    }
}


/// <summary>
/// 计算层级
/// </summary>
inline int calculateLevel(double differ) {
    double resolution = differ * (M_PI * earthRadius * 1000 / 180);
    double area = 4 * M_PI * earthRadius * earthRadius * 1000 * 1000;
    double sideLength = sqrtThree / 3 * resolution;
    double unitArea = (3 * sqrtThree / 2) * pow(sideLength, 2);
    int level = (int) std::ceil(log(area / (unitArea * baseDiamondCount)) / log(2) / 2);
    return level;
}


/// <summary>
/// 计算分辨率
/// </summary>
inline double calculateDiffer(int level) {
    double area = 4 * M_PI * earthRadius * earthRadius * 1000 * 1000; // 总面积
    double unitArea = area / (pow(2, 2 * level) * 10); // 单位面积
    double sideLength = sqrt(unitArea / (3 * sqrtThree / 2));
    double resolution = sideLength / (sqrtThree / 3); // 分辨率
    double angle = resolution / (M_PI * earthRadius * 1000 / 180); // 角度
    return angle;
}

_NNU_DGGS_END